﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace demo.Web.AzureTables
{
    public class EmployeeDataSource
    {
        private EmployeeContext _ctx = new EmployeeContext();
        private string _myTableName = EmployeeContext.TableName;


        public EmployeeDataSource()
        {
        }


        public IQueryable<Employee> SelectAll(string deptID)
        {
            string pKey = Employee.MakePartitionKey(deptID);
            var results = from g in this._ctx.Employees
                          where g.PartitionKey == pKey
                          select g;
            return results;
        }

        
        /// <summary>
        /// 1 row via partition & row key.  Internal use only
        /// </summary>
        /// <returns></returns>
        private IQueryable<Employee> SelectRow(string pKey, string rowKey)
        {
            var results = from g in this._ctx.Employees
                          where g.PartitionKey == pKey
                             && g.RowKey == rowKey
                          select g;

            return results;
        }


        /// <summary>
        /// loads a SINGLE record from an immmutable composite ID (i.e. what you would find embedded in
        /// other records as a foriegn key)
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public Employee LoadFromCompositeID(string ID)
        {
            // assume not found
            Employee myRecord = null;

            // break apart the composite key into partition & row components
            string[] keyParts = ATSEntityBase.ParseID(ID);
            string pKey = keyParts[0];
            string rKey = keyParts[1];

            // read the (row key) record for this key.
            // assume that row may no longer be on file
            var qry = SelectRow(pKey, rKey);
            try
            {
                foreach (Employee dataRow in qry)
                {
                    myRecord = dataRow;
                    break;
                }
            }
            catch { }               // no longer on file

            return myRecord;
        }




        /// <summary>
        /// handle both insert and update functions (i.e. add if new, update if already on file)
        /// </summary>
        /// <param name="myItem"></param>
        public void Upsert(Employee myItem)
        {

            // see if row is already on file.
            // if not, this is really an add
            Employee origItem = null;
            if (myItem.PartitionKey != null && myItem.PartitionKey.Length > 0
                && myItem.RowKey != null && myItem.RowKey.Length > 0)
            {
                var qry = SelectRow(myItem.PartitionKey, myItem.RowKey);
                try
                {
                    foreach (Employee m in qry)
                    {
                        origItem = m;
                        break;
                    }
                }
                catch { ; }
            }

            if (origItem == null)
            {
                Add(myItem);
            }
            else
            {
                Update(myItem, origItem);

            }

            _ctx.SaveChanges();

        }


        private void Add(Employee myItem)
        {

            DateTime ts = DateTime.Now;
            myItem.CreateDate = ts;
            myItem.UpdateDate = ts;

            this._ctx.AddObject(_myTableName, myItem);
        }


        public void Update(Employee myItem, Employee origItem)
        {

            // make any entity changes that might need to be reflected in the keys
            myItem.UpdateDate = DateTime.Now;

            ATSEntityBase.CopyProperties(myItem, origItem);
            this._ctx.UpdateObject(origItem);

        }


    }
}